// File: dynamic_array.c 
//
//Modified by Pei Liu on 10/25/2011
//
//fuc add, get_used arraytrav
//

/* d_array is an expandable array type holding either int or pointers */

#include <stdlib.h>
#include "dynamic_array.h"


#define BASE_SIZE 16


/* allocates memory for and initializes a d_array and return pointer to it */
d_array *create_d_array()
{
   d_array *p = malloc(sizeof(d_array));
   p->array = malloc(BASE_SIZE*sizeof(d_array));
   p->current_size = BASE_SIZE;
    p->used = 0;
   return p;
}

/**********************************************************/

/* wrapper around store to store ints */
int store_int(int i, int index, d_array *p)
{
   ptrint pi;
   pi.ival = i;
   return store(pi, index, p);
}

/**********************************************************/

/* wrapper around store to store pointers */
int store_ptr(void *ptr, int index, d_array *p)
{
   ptrint pi;
   pi.pval = ptr;
   return store(pi, index, p);
}

/**********************************************************/

/* hold[index] = i doubling size of hold if necessary
   returns whether size increment was successful */
int store(ptrint i, int index, d_array *p)
{
   if (!p->array)                     /* make sure array exists */
   {
      p->array = malloc(BASE_SIZE*sizeof(ptrint));
      p->current_size = BASE_SIZE;
   }
   /* check index for range -- if out of range double size of hold */
   if (index >=  p->current_size)
   {
      /*if (!grow(p))
          return 0;*/
       printf("%d ", grow(p));
       /* memory allocation failed */
   }
   p->array[index] = i;
   p->used++;
   return 1;
}

/**********************************************************/

/* returns element of array without range checking -- disregard type */
ptrint retrieve(int index, d_array *p)
{
   return p->array[index];
}

/**********************************************************/

/* returns element of array without range checking -- returns int */
int retrieve_int(int index, d_array *p)
{
   return p->array[index].ival;
}

/**********************************************************/

/* returns element of array without range checking -- returns pointer */
void *retrieve_ptr(int index, d_array *p)
{
   return p->array[index].pval;
}

/**********************************************************/

/* doubles size of hold[] */
int grow(d_array *p)
{
   int old_size = p->current_size;
   p->current_size *= 2;
   /* newhold[] has double size of p->array */
   ptrint *newhold;
   if (!(newhold = malloc(p->current_size*sizeof(ptrint))))
      return 0;
    /* copy contents of p->array[] to newhold[] */
   int k;
   for (k = 0; k < old_size; k++)
      newhold[k] = p->array[k];
   free(p->array);
   p->array = newhold;
    return 1;
}
/**********************************************************/

/* get number of used slots */
int get_used(d_array *p)
{
    return(p -> used);
}
/**********************************************************/

/* d_array traversal */

void arraytrav(FILE* fout,d_array* p)
{
    
    int i = 0;
	for(i = 0; i < get_used(p); i++)
    {
        if(fout == NULL)
            printf("%d\n", retrieve_int(i, p));
        else
            fprintf(fout,"%d\n", retrieve_int(i, p));
    }
}
